package org.baitu.zzim.handler;

import io.netty.channel.*;
import io.netty.handler.codec.http.*;
import io.netty.handler.codec.http.cookie.Cookie;
import io.netty.handler.codec.http.cookie.ServerCookieDecoder;
import io.netty.util.AttributeKey;
import org.baitu.zzim.service.ChannelManager;
import org.baitu.zzim.util.JwtUtil;
import org.baitu.zzim.util.RedisUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.Objects;


@Component
public class JwtHandshakeAuthHandler extends SimpleChannelInboundHandler<FullHttpRequest> {

    private final ChannelManager channelManager;
    private final RedisUtil redisUtil;
    // 定义一个 AttributeKey，用来存用户id
    public static final AttributeKey<String> USER_ID_ATTR = AttributeKey.valueOf("userId");

    public JwtHandshakeAuthHandler(ChannelManager channelManager, RedisUtil redisUtil) {
        this.channelManager = channelManager;
        this.redisUtil = redisUtil;
    }

    @Override
    protected void channelRead0(ChannelHandlerContext ctx, FullHttpRequest req) throws Exception {
        if (isWebSocketUpgradeRequest(req)) {
            String jwt = extractJwt(req);
            String userId = JwtUtil.parseUserId(jwt);

            if (jwt == null || userId == null || userId.isEmpty()) {
                sendHttpResponse(ctx, req, new DefaultFullHttpResponse(
                        HttpVersion.HTTP_1_1, HttpResponseStatus.UNAUTHORIZED));
                ctx.close();
                return;
            }
            // 把userId保存到channel属性中
            ctx.channel().attr(USER_ID_ATTR).set(userId);
            channelManager.addChannel(userId, ctx.channel());
            // 传递给后续handler继续处理握手
            ctx.fireChannelRead(req.retain());
        } else {
            // 非握手请求继续传递
            ctx.fireChannelRead(req.retain());
        }
    }

    private boolean isWebSocketUpgradeRequest(FullHttpRequest req) {
        return "websocket".equalsIgnoreCase(req.headers().get(HttpHeaderNames.UPGRADE));
    }

    private String extractJwt(FullHttpRequest req) {
        // 1. 优先从 Authorization header 里拿 Bearer token
        String authHeader = req.headers().get(HttpHeaderNames.AUTHORIZATION);
        if (authHeader != null && authHeader.startsWith("Bearer ")) {
            return authHeader.substring(7);
        }
        // 2. 如果没有，可以从 Cookie 里拿，示例简化，生产建议用更完善的cookie解析库
        String cookieStr = req.headers().get(HttpHeaderNames.COOKIE);
        if (cookieStr != null) {
            for (Cookie cookie : ServerCookieDecoder.STRICT.decode(cookieStr)) {
                if ("jwt".equals(cookie.name())) {
                    return cookie.value();
                }
            }
        }
        // 找不到token，返回null
        return null;
    }

    private void sendHttpResponse(ChannelHandlerContext ctx, FullHttpRequest req, FullHttpResponse res) {
        ChannelFuture f = ctx.channel().writeAndFlush(res);
        if (!HttpUtil.isKeepAlive(req) || res.status().code() != 200) {
            f.addListener(ChannelFutureListener.CLOSE);
        }
    }
}